#include "Entities/VertexEntity.h"
#include "Entities/PolygonEntity.h"

using namespace cmn;
using namespace drawing;
using namespace editor_core;

VertexEntity::VertexEntity( PolygonEntity* parentPolygon, const Vec2& position ) :
	m_position( position ),
	m_parentPolygon( parentPolygon )
{}

VertexEntity::~VertexEntity() {}

void VertexEntity::GetChildren( ICollection<IEntity*>& children ) const {
	children.Clear();
}

void VertexEntity::GetParents( ICollection<IEntity*>& parents ) const {
	parents.Clear();
	parents.Add( m_parentPolygon );
}

void VertexEntity::GetProperties( ICollection<Property>& properties ) const {
	properties.Clear();

	properties.Add( Property( 401, "X", PropertyValue( m_position.X ) ) );
	properties.Add( Property( 402, "Y", PropertyValue( m_position.Y ) ) );
}

bool VertexEntity::TryUpdateProperty( Property& property ) const {
	switch( property.GetKey() ) {
		case 401:
			property.SetValue( PropertyValue( m_position.X ) );
			return true;
		case 402:
			property.SetValue( PropertyValue( m_position.Y ) );
			return true;
		default:
			return false;
	}
}

bool VertexEntity::TryUpdateFromProperty( const Property& property ) {
	switch( property.GetKey() ) {
		case 401:
			m_position.X = property.GetValue().GetFloat();
			return true;
		case 402:
			m_position.Y = property.GetValue().GetFloat();
			return true;
		default:
			return false;
	}
}

void VertexEntity::Tick() {}

void VertexEntity::DrawInner( IDrawer* drawer ) {
	drawer->DrawCircle( Circle( GetAbsolutePosition(), GetRadius() ) );
}

Vec2 VertexEntity::GetAbsolutePosition() const {
	return m_parentPolygon->GetPosition() * m_position;
}

void VertexEntity::SetAbsolutePosition( const Vec2& position ) {
	Transform parentPos = m_parentPolygon->GetPosition();
	Vec4 targetPosition4 = Vec4( position.X, position.Y, 0.0f, 1.0f );
	Vec4 targetRelativePos4 = targetPosition4 * parentPos.GetInvMatrix();
	m_position = Vec2( targetRelativePos4.X / targetRelativePos4.W, targetRelativePos4.Y / targetRelativePos4.W );
}

Vec2 VertexEntity::Move( const Vec2& vector ) {
	Vec2 currentPos = GetAbsolutePosition();
	SetAbsolutePosition( currentPos + vector );
	Vec2 newPos = GetAbsolutePosition();
	return newPos - currentPos;
}

void VertexEntity::Delete() {
	m_parentPolygon->RemoveVertex( this );
}

void VertexEntity::Undelete() {
	m_parentPolygon->AddVertex( this );
}

bool VertexEntity::Contains( const Vec2& point ) const {
	float dist = Distance( GetAbsolutePosition(), point );
	return dist <= GetRadius();
}
